import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;


public class Machine {

	private Location actual;
	
	private Location destiny;
	
	private double altitude;
	
	private int id;
	
	private ArrayList<Integer> vehiclesOnRadius = new ArrayList<Integer>();
	
	private ArrayList<Integer> vehiclesToChangeAlt = new ArrayList<Integer>();
	
	private int nearStation = 0;
	
	private int OnStation = 0;
	
	private boolean moving = false;
	
	private boolean outBatt = false;
	
	private double TravelBearing;
	
	private Socket socket;
	
	private PrintWriter EmulOut;
	
	private PrintWriter SimOut;
	
	private int battery;
	
	private String _address;
	
	private int _port;
	
	
	
	public Machine(int ide, Location initial, int emulport, PrintWriter out, String address, int netport, int batt, double alt){
		
		this.id = ide;
		
		this.actual = initial;
		
		this.SimOut = out;
		
		this.battery = batt;
		
		this._address = address;
		
		this._port = netport;
		
		this.altitude = alt;
		
		try {
			
			this.socket = new Socket(_address, emulport);
			
			this.EmulOut = new PrintWriter(this.socket.getOutputStream(), true);
			
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	public PrintWriter getEmulOut(){
		
		return this.EmulOut;
	}
	
	public PrintWriter getSimOut(){
		
		return this.SimOut;
	}
	
	public boolean isMoving(){
		
		return this.moving;
	}
	
	public void Start(Location dest){
		
		this.destiny = dest;
		this.moving = true;
		this.actual.setAltitude(100);
		this.TravelBearing = this.actual.getBearing(dest);
	}
	
	public void Stop(){
		
		this.altitude = 0;
		this.moving = false;
	}
	
	public int getID(){
		
		return this.id;
	}
	
	public Location getLocation(){
		
		return this.actual;
	}
	
	public void outBattery(){
		
		Stop();
		this.outBatt = true;
	}
	
	public int getBattery(){
		
		return this.battery;
	}
	
	public String getAddress(){
		
		return this._address;
	}
	
	public int getPort(){
		
		return this._port;
	}
	
	public Location move(){
		
		if(this.battery >= 10){
		
			if(this.actual.getDistance(this.destiny) < 0.014){
			//if(Math.abs(this.TravelBearing-this.actual.getBearing(this.destiny)) > 90){
				
				this.actual = this.destiny ;
				Stop();
				
			}else			
				
				this.actual.move(33, this.actual.getBearing(this.destiny));
			
			// Reduzir bateria
			this.battery -= 10;
			if(this.battery < 10)
				outBattery();
		

		}
		else
			outBattery();
		
		
		return this.actual;
	}
	
	public void kill(){
		
		try {
			
			this.socket.close();
			
		} catch (IOException e) {

			e.printStackTrace();
		}
	}
	
	public void addVehicleOnRadius(int id){
		
		this.vehiclesOnRadius.add(id);
	}
	
	public void rmVehicleOnRadius(int id){
		for(int i=0; i<vehiclesOnRadius.size(); i++){
			if (vehiclesOnRadius.get(i).equals(id))
				vehiclesOnRadius.remove(i);
		}
		
	}
	
	public boolean isVehicleOnRadius(int id){
		for(int i=0; i<vehiclesOnRadius.size(); i++){
			if (vehiclesOnRadius.get(i).equals(id))
				return true;
		}
		return false;
	}

	public void addVehiclesToChangeAlt(int id) {
		vehiclesToChangeAlt.add(id);
	}

	public void rmVehiclesToChangeAlt(int id) {
		vehiclesToChangeAlt.remove(vehiclesToChangeAlt.indexOf(id));
		//vehiclesToChangeAlt.indexOf(id)
	}
	
	public boolean isVehiclesToChangeAlt(int id){
		for(int i=0; i<vehiclesToChangeAlt.size(); i++){
			if (vehiclesToChangeAlt.get(i).equals(id))
				return true;
		}
		return false;
	}
	
	public void riseAltitude(){
		
		if(this.battery < 200)
			outBattery();
		else{
			this.altitude += 100;
			this.battery -= 200;
		}
	}
	
	public double getAltitude(){
		
		return this.altitude;
	}
	
	public void normalize(){
		
		if(this.altitude < 200){
			if(this.battery < (200-this.altitude)*2)
				outBattery();
			else
				this.battery -= (200-this.altitude)*2;
		}
		this.altitude = 200;
		
	}
	
	public boolean isOnStation(int id){
		
		if(this.OnStation == id)
			return true;
		else
			return false;
	}
	
	public void onStation(int id){
		this.OnStation = id;
	}
	
	public void notOnStaton(){
		this.OnStation = 0;
	}
	
	public boolean isStationNear(int id){
		
		if(this.nearStation == id)
			return true;
		else
			return false;
	}
	
	public void putStation(int id){
		
		this.nearStation = id;
	}

	public void rmStation(int id){
		this.nearStation = 0;
	}
	
	public void setBattery(int batt){
		
		this.battery = batt;
		if(this.battery == 0)
			outBattery();
		else{
			this.outBatt = false;
			this.SimOut.println("Changes "+ this.battery+" "+this.altitude);
		}
			
	}
	
}
